package algorithm.markovLink;

import static algorithm.markovLink.Utils.idx2Char;

import java.util.Random;

public class GenerateWord {
	private static int FIRST_LETTER;
	private static int END_LETTER;
	private int[][] matrix;
	private StringBuilder sb;
	private int row;
	private Random ran;
	private static int MAX_COUNTS;

	public GenerateWord(int[][] matrix) {
		super();
		this.matrix = matrix;
		ran = new Random();
		sb = new StringBuilder();
		MAX_COUNTS = matrix.length - 1;
		FIRST_LETTER = MAX_COUNTS;
		END_LETTER = MAX_COUNTS - 1;
	}

	public String generate_word(int minLen, int maxLen) {
		String ret = "";
		if (minLen < 1)
			return ret;
		if (maxLen < minLen)
			return ret;
		while (ret.length() < minLen || ret.length() > maxLen) {
			row = select_letter(FIRST_LETTER);
			while (true) {
				row = select_letter(row);
				if (row == END_LETTER)
					break;
			}
			ret = sb.toString();
			sb.setLength(0);
		}
		return ret;
	}

	/**
	 * 
	 * @param row
	 * @return 由给定的row,以一定的概率返回其它的row
	 */
	private int select_letter(int row) {
		int i = 0;
		int sum = 0;
		char c;

		// pick the maximum value (for roulette selection);
		int max_val = ran.nextInt(matrix[row][MAX_COUNTS]) + 1;

		// perform the roulette wheel
		while (true) {
			// add in the current slot value
			sum += matrix[row][i];

			// if >= max_val, then selet this letter
			if (sum >= max_val) {
				c = idx2Char(i);
				if (c != '\0')
					sb.append(c);
				return i;
			}
			// otherwise, skip to the next letter in the row
			if (++i >= MAX_COUNTS)
				i = 0;
		}
	}
}
